package com.ztjava.ask.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.jfinal.core.Controller;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Page;
import com.xiaoleilu.hutool.date.DateUtil;
import com.ztjava.ask.model.AskAnswer;
import com.ztjava.ask.model.AskCatalog;
import com.ztjava.ask.model.AskDing;
import com.ztjava.ask.model.AskFav;
import com.ztjava.ask.model.AskQuestion;
import com.ztjava.ask.model.AskReply;
import com.ztjava.core.Constant;
import com.ztjava.core.base.BaseService;
import com.ztjava.core.bean.sub.MessageBean;
import com.ztjava.core.bean.sub.ScoreBean;
import com.ztjava.core.client.Client;
import com.ztjava.core.tool.ViewTool;
import com.ztjava.ext.auth.bean.AuthSession;
import com.ztjava.plugin.event.EventKit;
import com.ztjava.plugin.event.EventTag;
import com.ztjava.plugin.event.core.RequestEvent;

public class AskService extends BaseService{
	private static Logger logger = Logger.getLogger(AskService.class);
	public AskCatalog getCatalog(String custom){
		return AskCatalog.dao.findFirst("select * from "+AskCatalog.tablename+" where enable_flag='T' and custom=?",custom);
	}
	public List<AskCatalog> getSubCatalogList(Integer parent_id){
		return AskCatalog.dao.find("select * from "+AskCatalog.tablename+" where enable_flag='T' and parent_id=?",parent_id);
	}
	
	/***
	 * 获取分页问题
	 * @param client
	 * @param paramMap
	 * @return
	 */
	public Page<AskQuestion> getQuestionPage(Client client,Map<String,String[]> paramMap){
		return getQuestionPage(client, paramMap, null,false);
	}
	/***
	 * 我的回答的问题分页
	 * @param client
	 * @param paramMap
	 * @return
	 */
	public Page<AskAnswer> answerPage(Client client ,Map<String,String[]> paramMap){
		String[][] param = new String[][]{
				new String[]{"question_id",eq,"C.question_id"}
				,new String[]{"is_good",eq,"C.is_good"}
				,new String[]{"is_pass",eq,"C.is_pass"}
				,new String[]{"num",like_left,"A.num"}
				,new String[]{"status",eq,"A.status"}
				,new String[]{"title",like,"A.title"}
				,new String[]{"create_user",eq,"C.create_user"}
			};
		Page<AskAnswer> pd = AskAnswer.dao.paginate(
						getParaToInt(paramMap, client.getPageNumber(), 1), 
						getParaToInt(paramMap,client.getPageSize(),20),
						"select A.id,A.catalog_id,A.title,A.status,A.create_user,"
						+ "A.answer_count,A.score_count,A.score_type,A.click,"
						+ "A.create_time,A.is_pass,A.images,B.name as catalog_name"
						+ ",C.content,C.is_good,C.ding,C.is_pass as answer_is_pass,C.reply_count",
						"from "+AskAnswer.tablename+" C left join "+AskQuestion.tablename+" A ON C.question_id=A.id "
						+" left join "+AskCatalog.tablename+" B ON A.catalog_id=B.id "
						+ "where 1=1 "	+ whereSql(paramMap,param)
						+ orderby("A.",client, paramMap),whereParam(paramMap, param));
		changeBasedata(pd.getList(), new String[]{"status","ASK_STATUS"},
				new String[]{"score_type","SCORE_TYPE"},
				new String[]{"is_pass","SHIFOU"},
				new String[]{"is_good","SHIFOU"},
				new String[]{"answer_is_pass","SHIFOU"});
		changeUser(pd.getList(), new String[]{"create_user","name"}, new String[]{"create_user","headimg"});
		changeDatetime(pd.getList(), new String[]{"create_time","yyyy-MM-dd"});
		return pd;
	}
	/***
	 * 问题分页
	 * @param client
	 * @param paramMap
	 * @param fav_user_id
	 * @return
	 */
	public Page<AskQuestion> getQuestionPage(Client client,Map<String,String[]> paramMap,Integer loginUser,boolean isFav){
		String[][] param = new String[][]{
			new String[]{"num",like_left,"B.num"}
			,new String[]{"status",eq,"A.status"}
			,new String[]{"title",like,"A.title"}
			,new String[]{"create_user",eq,"A.create_user"}
			,new String[]{"image",notnull,"A.image"}
		};
		String sql = "from "+AskQuestion.tablename+" A "
				   + "left join " +AskCatalog.tablename+" B ON A.catalog_id=B.id";
		String field = "";
		if(isFav){
			sql = "from (select id,question_id from "+AskFav.tablename+" where create_user="+loginUser+") C "
			    + "left join "+ AskQuestion.tablename+" A ON A.id=C.question_id "
			    + "left join " +AskCatalog.tablename+" B ON A.catalog_id=B.id";
		}else {
			if(loginUser!=null&&loginUser>0){
				field = ",C.id as fav_id";
				sql = "from "+AskQuestion.tablename+" A "
					+ "left join " +AskCatalog.tablename +" B ON A.catalog_id=B.id "
					+ "left join (select id,question_id from "+AskFav.tablename+" where create_user="+loginUser+") C ON A.id=C.question_id ";
			}
		}
		Page<AskQuestion> pd = AskQuestion.dao.paginate(
				getParaToInt(paramMap, client.getPageNumber(), 1), 
				getParaToInt(paramMap,client.getPageSize(),20),
				"select A.id,A.catalog_id,A.title,A.status,A.create_user,"
				+ "A.answer_count,A.score_count,A.score_type,A.click,"
				+ "A.create_time,A.is_pass,A.images,B.name as catalog_name"+field,
				sql + " where 1=1 "
				+ whereSql(paramMap,param)
				+ orderby("A.",client, paramMap),whereParam(paramMap, param));
		changeBasedata(pd.getList(), new String[]{"status","ASK_STATUS"},
				new String[]{"score_type","SCORE_TYPE"},
				new String[]{"is_pass","SHIFOU"});
		changeUser(pd.getList(), new String[]{"create_user","name"}, 
				new String[]{"create_user","headimg"});
		changeDatetime(pd.getList(), new String[]{"create_time","yyyy-MM-dd"});
		return pd;
	}

	/***
	 * 问题详情
	 * @param controller
	 * @param id
	 * @param user_id
	 */
	public void showQuestion(Controller controller,Integer id,AuthSession authSession){
		AskQuestion askQuestion = AskQuestion.dao.findById(id);
		AskCatalog askCatalog = AskCatalog.dao.findById(askQuestion.getInt("catalog_id"));
		changeBasedata(askQuestion, new String[]{"status","ASK_STATUS"}, new String[]{"score_type","SCORE_TYPE"});
		changeUser(askQuestion,new String[]{"create_user","name"},new String[]{"create_user","headimg"});
		
		
		if(authSession!=null){
			AskFav askFav = AskFav.dao.findFirst("select id from "+AskFav.tablename+" where question_id=? and create_user=?",id,authSession.getId());
			controller.setAttr("askFav", askFav);
		}
		askQuestion.set("click", askQuestion.getInt("click")+1).update();

		controller.setAttr("catalogPath", catalogPath(askCatalog.getStr("num")));
		controller.setAttr("askQuestion", askQuestion);
		controller.setAttr("askCatalog", askCatalog);
	}
	/***
	 * 获取问题回答列表
	 * @param question_id
	 * @param authSession
	 * @return
	 */
	public List<AskAnswer> getAnswerList(Integer question_id,AuthSession authSession){
		List<AskAnswer> answerList = new ArrayList<>();
		if(authSession!=null){
			answerList = AskAnswer.dao.find("select A.id,A.content,A.is_good"
					+ ",A.ding,A.reply_count,A.create_user,A.create_time,A.is_pass,B.id as ding_id"
					+ " from "+AskAnswer.tablename
					+ " A left join (select id,answer_id from "+AskDing.tablename+" where create_user=?) B ON A.id=B.answer_id "
					+ "where A.question_id=? order by A.is_good desc,A.ding desc,A.id asc",authSession.getId(),question_id);
		}else {
			answerList = AskAnswer.dao.find("select A.id,A.content,A.is_good"
					+ ",A.ding,A.reply_count,A.create_user,A.create_time,A.is_pass"
					+ " from "+AskAnswer.tablename
					+" where A.question_id=? order by A.is_good desc,A.ding desc,A.id asc",question_id);
		}
		
		changeUser(answerList, new String[]{"create_user","name"});
		
		List<AskReply> replyList = AskReply.dao.find("select id,answer_id,content,create_user,create_time,is_pass from "
				+AskReply.tablename+" where question_id=? order by id asc",question_id);
		
		changeUser(replyList, new String[]{"create_user","name"});
		if(answerList.size()>0&&replyList.size()>0){
			for(int i=0;i<answerList.size();i++){
				List<AskReply> itemList = new ArrayList<>();
				for(int j=0;j<replyList.size();j++){
					if(replyList.get(j).getInt("answer_id").equals(answerList.get(i).getInt("id"))){
						itemList.add(replyList.get(j));
					}
				}
				if(itemList.size()>0){
					answerList.get(i).put("replyList", itemList);
				}
			}
		}
		return answerList;
	}
	/***
	 * 分类路径
	 * @param num
	 * @return
	 */
	public List<AskCatalog> catalogPath(String num){
		num = num.substring(0,num.length()-1);
		return AskCatalog.dao.find("select * from "+AskCatalog.tablename+" where id in ("+num+") order by id asc");
	}
	
	/****
	 * 新问题
	 * @param catalog_id
	 * @param title
	 * @param content
	 * @param images
	 * @param score
	 * @param user_id
	 * @return
	 */
	public Ret insertQuestion(Integer catalog_id,String title,String content,
			String images,Integer score,Integer user_id){
		AskCatalog askCatalog = AskCatalog.dao.findById(catalog_id);
		Ret ret = new Ret();
		if(askCatalog==null||askCatalog.getStr("enable_flag").equals("F")){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "分类不可用！");
			return ret;
		}
		if(askCatalog.getStr("is_select").equals("F")){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "当前分类新建提问！");
			return ret;
		}
		AskQuestion askQuestion = new AskQuestion();
		askQuestion.set("catalog_id", catalog_id);
		askQuestion.set("title",title);
		askQuestion.set("content",content);
		askQuestion.set("images",images);
		askQuestion.set("is_pass", ViewTool.param("ASK_QUESTION_PASS","T"));
		askQuestion.set("score_type", ViewTool.param("ASK_SCORE"));
		askQuestion.set("score_count", score);
		Integer close = Integer.parseInt(ViewTool.param("ASK_CLOSE"));
		if(close>0){
			askQuestion.set("close_time",DateUtil.offsetDay(new Date(), close).toTimestamp());
		}
		askQuestion.set("create_user", user_id);
		askQuestion.set("status", "READY");
		if(score>0){
			List<Ret> scoreRet = EventKit.postRemote(EventTag.SCORE_UPDATE, 
					new RequestEvent(new ScoreBean(user_id,  ViewTool.param("ASK_SCORE"), -score,"问答积分消耗", user_id)));
			if(scoreRet.size()==0){
				logger.error("积分扣减事件未响应！");
				return Ret.create(Constant.RESULT,Constant.ERROR).set(Constant.MESSAGE, "积分扣减事件未响应！");
			}
			if(scoreRet.get(0).getStr(Constant.RESULT).equals(Constant.ERROR)){
				return scoreRet.get(0);
			}
		}
		askQuestion.save();
		return Ret.create(Constant.RESULT,Constant.SUCCESS).set(Constant.MESSAGE, "问题提交成功！")
				.set("id",askQuestion.getInt("id")).set("is_pass", askQuestion.getStr("is_pass"));
	}
	
	/***
	 * 新回答
	 * @param question_id
	 * @param content
	 * @param image
	 * @param user_id
	 * @return
	 */
	public Ret insertAnswer(Integer question_id,String content,String image,Integer user_id){
		AskQuestion askQuestion = AskQuestion.dao.findById(question_id);
		Ret ret = new Ret();
		if(!askQuestion.getStr("status").equals("READY")){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "只能回答未解决问题！");
			return ret;
		}
		if(!user_id.equals(2)&&askQuestion.getInt("create_user").equals(user_id)){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "不能回答自己的问题！");
			return ret;
		}
		AskAnswer askAnswer = AskAnswer.dao.findFirst("select id from "+AskAnswer.tablename+" where question_id=? and create_user=?",question_id,user_id);
		if(askAnswer!=null){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "已经回答过不能再次回答！");
			return ret;
		}
		askAnswer = new AskAnswer();
		askAnswer.set("question_id", question_id);
		askAnswer.set("content", content);
		askAnswer.set("image", image);
		askAnswer.set("is_pass", ViewTool.param("ASK_ANSWER_PASS","T"));
		askAnswer.set("create_user", user_id);
		askAnswer.save();
		
		MessageBean messageBean = new MessageBean("ASK","ANSWER",question_id, null,
				askQuestion.getInt("create_user"),content, user_id);
		EventKit.postRemote(EventTag.AUTH_MESSAGE, new RequestEvent(messageBean));
		
		askQuestion.set("answer_count", AskAnswer.dao.findFirst("select count(id) as amount from "+AskAnswer.tablename+" where question_id=?",question_id).getLong("amount").intValue()).update();

		ret.set(Constant.RESULT, Constant.SUCCESS);
		ret.set(Constant.MESSAGE,"回答成功！");
		ret.set("is_pass", askAnswer.getStr("is_pass"));
		return ret;
	}
	/****
	 * 新回复
	 * @param answer_id
	 * @param content
	 * @param image
	 * @param user_id
	 * @return
	 */
	public Ret insertReply(Integer answer_id,String content,String image,Integer user_id){
		AskAnswer askAnswer = AskAnswer.dao.findById(answer_id);
		Ret ret = new Ret();
		if(askAnswer==null){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "回答不存在！");
			return ret;
		}
		AskQuestion askQuestion = AskQuestion.dao.findById(askAnswer.getInt("question_id"));
		if(askQuestion==null) {
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "问题不存在！");
			return ret;
		}
		AskReply askReply = new AskReply();
		askReply.set("question_id", askQuestion.getInt("id"));
		askReply.set("answer_id", answer_id);
		askReply.set("content", content);
		askReply.set("image", image);
		askReply.set("is_pass", ViewTool.param("ASK_REPLY_PASS","T"));
		askReply.set("create_user", user_id);
		askReply.save();
		//消息通知
		List<AskReply> replyList = AskReply.dao.find("select create_user from "+AskReply.tablename+" where answer_id=? and create_user<>? and create_user<>? and create_user<>? group by create_user",answer_id,user_id,askQuestion.getInt("create_user"),askAnswer.getInt("create_user"));
		if(!user_id.equals(askQuestion.getInt("create_user"))){
			MessageBean messageBean = new MessageBean("ASK","REPLY",askAnswer.getInt("question_id"),askAnswer.getInt("id"),
					askQuestion.getInt("create_user"),content, user_id);
			EventKit.postRemote(EventTag.AUTH_MESSAGE, new RequestEvent(messageBean));
		}
		if(!user_id.equals(askAnswer.getInt("create_user"))){
			MessageBean messageBean = new MessageBean("ASK","REPLY",askAnswer.getInt("question_id"),askAnswer.getInt("id"),
					askAnswer.getInt("create_user"),content, user_id);
			EventKit.postRemote(EventTag.AUTH_MESSAGE, new RequestEvent(messageBean));
		}
		for(int i=0;i<replyList.size();i++){
			MessageBean messageBean = new MessageBean("ASK","REPLY",askAnswer.getInt("question_id"),askAnswer.getInt("id"),
					replyList.get(i).getInt("create_user"),content, user_id);
			EventKit.postRemote(EventTag.AUTH_MESSAGE, new RequestEvent(messageBean));
		}
		
		askAnswer.set("reply_count", AskReply.dao.findFirst("select count(id) as amount from "+AskReply.tablename+" where answer_id=?",answer_id).getLong("amount").intValue()).update();

		ret.set(Constant.RESULT, Constant.SUCCESS);
		ret.set(Constant.MESSAGE,"回复成功！");
		ret.set("is_pass", askReply.getStr("is_pass"));
		return ret;
	}
	/*****
	 * 采纳答案（管理员）
	 * @param answer_id
	 * @param user_id
	 * @return
	 */
	public Ret goodAnswerAdmin(Integer answer_id,Integer user_id){
		Ret ret = new Ret();
		AskAnswer askAnswer = AskAnswer.dao.findById(answer_id);
		if(askAnswer==null){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "找不到回答！");
			return ret;
		}
		askAnswer.set("is_good", "T").update();
		AskQuestion askQuestion = AskQuestion.dao.findById(askAnswer.getInt("question_id"));
		if(!askQuestion.getStr("status").equals("READY")){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "状态不正确！");
			return ret;
		}
		askQuestion.set("status", "RESOLVED").update();
		ret.set(Constant.RESULT, Constant.SUCCESS);
		ret.set(Constant.MESSAGE,"回答采纳成功！");
		return ret;
	}
	/*****
	 * 采纳答案
	 * @param answer_id
	 * @param user_id
	 * @return
	 */
	public Ret goodAnswer(Integer answer_id,Integer user_id){
		AskAnswer askAnswer = AskAnswer.dao.findById(answer_id);
		Ret ret = new Ret();
		if(askAnswer==null){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "找不到回答！");
			return ret;
		}
		AskQuestion askQuestion = AskQuestion.dao.findById(askAnswer.getInt("question_id"));
		if(!askQuestion.getStr("status").equals("READY")){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "状态不正确！");
			return ret;
		}
		if(!askQuestion.getInt("create_user").equals(user_id)){
			ret.set(Constant.RESULT, Constant.ERROR);
			ret.set(Constant.MESSAGE, "仅允许创建人采纳答案！");
			return ret;
		}
		askAnswer.set("is_good", "T").update();
		askQuestion.set("status", "RESOLVED").update();
		if(askQuestion.get("score")!=null&&askQuestion.getInt("score")>0){
			List<Ret> scoreRet = EventKit.postRemote(EventTag.SCORE_UPDATE, 
					new RequestEvent(new ScoreBean(askAnswer.getInt("create_user"), askQuestion.getStr("score_type"), askQuestion.getInt("score"),"回答被采纳！", user_id)));
			if(scoreRet.size()==0){
				logger.error("积分奖励事件未响应！");
				return Ret.create(Constant.RESULT,Constant.ERROR).set(Constant.MESSAGE, "积分奖励事件未响应！");
			}
			if(scoreRet.get(0).getStr(Constant.RESULT).equals(Constant.ERROR)){
				return scoreRet.get(0);
			}
		}

		ret.set(Constant.RESULT, Constant.SUCCESS);
		ret.set(Constant.MESSAGE,"回答采纳成功！");
		return ret;
	}
	/****
	 * 更新收藏
	 * @param question_id
	 * @param user_id
	 * @return
	 */
	public Ret updateFav(Integer question_id,Integer user_id){
		Ret ret = new Ret();
		AskFav askFav = AskFav.dao.findFirst("select id from "+AskFav.tablename+" where question_id=? and create_user=?",question_id,user_id);
		if(askFav==null){
			askFav = new AskFav();
			askFav.set("question_id", question_id);
			askFav.set("create_user", user_id);
			askFav.save();
			ret.set(Constant.RESULT, Constant.SUCCESS);
			ret.set(Constant.MESSAGE,"收藏成功！");
			ret.set("fav",true);
		}else {
			askFav.delete();
			ret.set(Constant.RESULT, Constant.SUCCESS);
			ret.set(Constant.MESSAGE,"取消收藏成功！");
			ret.set("fav",false);
		}
		return ret;
	}
	/****
	 * 更新赞
	 * @param answer_id
	 * @param user_id
	 * @return
	 */
	public Ret updateDing(Integer answer_id,Integer user_id){
		Ret ret = new Ret();
		if(answer_id==null||answer_id==0){
			ret.set(Constant.RESULT, Constant.SUCCESS);
			ret.set(Constant.MESSAGE,"不存在的回答！");
			return ret;
		}
		AskDing askDing = AskDing.dao.findFirst("select id from "+AskDing.tablename+" where answer_id=? and create_user=?",answer_id,user_id);
		if(askDing==null){
			askDing = new AskDing();
			askDing.set("answer_id", answer_id);
			askDing.set("create_user", user_id);
			askDing.save();
			ret.set(Constant.RESULT, Constant.SUCCESS);
			ret.set(Constant.MESSAGE,"赞成功！");
			ret.set("ding",true);
		}else {
			askDing.delete();
			ret.set(Constant.RESULT, Constant.SUCCESS);
			ret.set(Constant.MESSAGE,"取消赞成功！");
			ret.set("ding",false);
		}
		AskAnswer askAnswer = new AskAnswer();
		askAnswer.set("id", answer_id);
		askAnswer.set("ding", AskDing.dao.findFirst("select count(id) as amount from "+AskDing.tablename+" where answer_id=?",answer_id).getLong("amount").intValue());
		askAnswer.update();
		return ret;
	}
	/***
	 * 树形子分类
	 * @param params
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<AskCatalog> treeCatalog(Map<String, String[]> params){
		Integer parent_id = params.get("parent_id")==null?0:Integer.parseInt(params.get("parent_id")[0]);
		String where = "";
		if(parent_id>0){
			AskCatalog askCatalog = AskCatalog.dao.findById(parent_id);
			if(askCatalog!=null){
				where = " and num like '"+askCatalog.getStr("num")+"%' and id<>"+parent_id+" ";
			}
		}
		String[][] searchArr = new String[][]{ new String[]{"is_good",eq}};
		List<AskCatalog> catalogList = AskCatalog.dao.find("select id,parent_id,num,name,icon,image,is_good,is_select from "
				+ AskCatalog.tablename+" where enable_flag='T' "
				+ whereSql(params, searchArr) 
				+ where+" AND enable_flag='T' order by sort asc,id asc",
				whereParam(params, searchArr));
		return treeLevel(catalogList,parent_id);
	}
	/***
	 * 子分类
	 * @param params
	 * @return
	 */
	public List<AskCatalog> catalogList(Map<String, String[]> params){
		String[][] searchArr = new String[][]{ new String[]{"is_good",eq},new String[]{"parent_id",eq}};
		return AskCatalog.dao.find("select id,parent_id,num,name,icon,image,is_good,is_select from "
				+AskCatalog.tablename+" where enable_flag='T' "
				+ whereSql(params, searchArr)
				+" order by sort asc,id asc",
				whereParam(params, searchArr));
	}
}
